package net.guerlab.sdk.anubis.request;

import java.lang.reflect.ParameterizedType;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.databind.ObjectMapper;

import net.guerlab.sdk.anubis.AnubisConstants;
import net.guerlab.sdk.anubis.AnubisException;
import net.guerlab.sdk.anubis.Format;
import net.guerlab.sdk.anubis.Method;
import net.guerlab.sdk.anubis.response.AbstractResponse;

/**
 * 抽象请求
 * 
 * @author guer
 *
 * @param <T>
 *            响应类型
 */
public abstract class AbstractRequest<T extends AbstractResponse<?>> {

    private static final Logger LOGGER = LoggerFactory.getLogger(AbstractRequest.class);

    public static final String SIGNATURE_KEY_NAME = "signature";

    /**
     * 
     */
    protected ObjectMapper objectMapper;

    /**
     * 响应体
     */
    protected T response;

    /**
     * 获取响应对象类型
     * 
     * @return 响应对象类型
     */
    @SuppressWarnings("unchecked")
    public Class<T> getResponseClass() {
        return (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    }

    /**
     * 构造请求URI
     * 
     * @param builder
     *            请求URI构造器
     * @param appId
     *            appId
     * @param secretKey
     *            secretKey
     */
    public abstract void createRequestUri(
            StringBuilder builder,
            String appId,
            String secretKey);

    /**
     * 执行请求
     * 
     * @param responseData
     *            响应数据
     */
    protected void parseResponse0(
            String responseData) {
        try {
            response = objectMapper.readValue(responseData, getResponseClass());
        } catch (Exception e) {
            LOGGER.debug(e.getMessage(), e);
        }

        if (response == null) {
            throw new AnubisException("response body is empty");
        }

        if (AnubisConstants.CODE_SUCCESS != response.getCode()) {
            throw new AnubisException("request fail[code=" + response.getCode() + ", msg=" + response.getMsg() + "]");
        }
    }

    /**
     * 获取请求内容
     * 
     * @return 请求内容
     */
    public abstract String requestBody();

    /**
     * 获取请求方式
     * 
     * @return 请求方式
     */
    public Method method() {
        return Method.POST;
    }

    /**
     * 获取内容格式
     * 
     * @return 内容格式
     */
    public Format format() {
        return Format.JSON;
    }

    /**
     * 执行请求
     * 
     * @param responseData
     *            响应数据
     * @return 响应实体
     */
    public AbstractRequest<T> parseResponse(
            String responseData) {
        parseResponse0(responseData);
        return this;
    }

    /**
     * 获取响应实体
     * 
     * @return 响应实体
     */
    public final T getResponse() {
        return response;
    }

    /**
     * 设置response
     *
     * @param response
     *            response
     */
    public void setResponse(
            T response) {
        this.response = response;
    }

    /**
     * 返回 objectMapper
     *
     * @return objectMapper
     */
    public ObjectMapper getObjectMapper() {
        return objectMapper;
    }

    /**
     * 设置objectMapper
     *
     * @param objectMapper
     *            objectMapper
     */
    public void setObjectMapper(
            ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }
}
